﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockManagement.Model;
using StockManagement.Helper;
using StockManagement.Commands;
using System.Collections.ObjectModel;

namespace StockManagement.ViewModels
{
    public class OutwardMaterialViewModel:BaseViewModel
    {
        MaterialViewModel _materialVM;        
        DateTime _date;        
        string _purchaser;

        DelegateCommand _updateCommand;
        DelegateCommand _discardCommand;
                
        public delegate bool MaterialDeliveredDelegate(MaterialViewModel materialVM);
        public event MaterialDeliveredDelegate MaterialDelivered;

        ObservableCollection<MaterialViewModel> _OutwardMaterialCollection;

        public OutwardMaterialViewModel(ObservableCollection<MaterialViewModel> materialCollection)
        {
            PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(EditMaterialViewModel_PropertyChanged);
            _OutwardMaterialCollection = new ObservableCollection<MaterialViewModel>(materialCollection.Where(p => p.MaterialType == EnumMaterialType.Trading));
            materialCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(materialCollection_CollectionChanged);
            _updateCommand = new DelegateCommand(ExecuteUpdateMaterialCommand, CanExecuteCommand);
            _discardCommand = new DelegateCommand(ExecuteDiscardCommand, CanExecuteCommand);
            SelectedMaterial = OutwardMaterialCollection.FirstOrDefault();
        }

        void EditMaterialViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "SelectedMaterial":
                    InitializeProperties();
                    break;
                default:
                    break;
            }

            RaiseCanExecuteCommand();
        }

        private void RaiseCanExecuteCommand()
        {
            UpdateCommand.RaiseCanExecuteChanged();
            DiscardCommand.RaiseCanExecuteChanged();
        }

        void materialCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    if (e.NewItems == null || e.NewItems.Count < 1)
                        return;

                    var matVM = e.NewItems[0] as MaterialViewModel;
                    if (matVM == null)
                        return;

                    var item = OutwardMaterialCollection.FirstOrDefault(p => p.MaterialID == matVM.MaterialID);
                    if (item != null)
                        return;

                    if (matVM.MaterialType == EnumMaterialType.Trading)
                    {
                        OutwardMaterialCollection.Add(matVM);
                        SelectedMaterial = matVM;
                    }
                    break;
                case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                    if (e.OldItems == null || e.OldItems.Count < 1)
                        return;
                    matVM = e.OldItems[0] as MaterialViewModel;
                    if (matVM == null)
                        return;

                    item = OutwardMaterialCollection.FirstOrDefault(p => p.MaterialID == matVM.MaterialID);
                    if (item == null)
                        return;

                    OutwardMaterialCollection.Remove(item);
                    break;
            }
        }

        private void InitializeProperties()
        {
            if (_materialVM == null)
                return;

            Date = DateTime.Now;
            Purchaser = string.Empty;
        }
                
        public string Purchaser
        {
            get { return _purchaser; }
            set
            {
                _purchaser = value;
                OnPropertyChanged("Purchaser");
            }
        }

        public DateTime Date
        {
            get { return _date; }
            set
            {
                _date = value;
                OnPropertyChanged("Date");
            }
        }
        
        public DelegateCommand UpdateCommand
        {
            get
            {
                return _updateCommand;
            }
        }

        public DelegateCommand DiscardCommand
        {
            get { return _discardCommand; }
        }

        private bool CanExecuteCommand(object parameter)
        {
            return (_materialVM != null && Purchaser != null && !string.IsNullOrEmpty(Purchaser.Trim()));
        }

        private void ExecuteUpdateMaterialCommand(object parameter)
        {
            string strmessage = string.Format("Do you want to mark the Material '{0}' as Delivered?", SelectedMaterial.MaterialName);
            var result = ShowConfirmationMessageBox(strmessage, "Deliver Material");
            if (!result)
                return;

            if (!_materialVM.UpdateMaterial(UpdateType.Deliver, DateTime.Now,_materialVM.VendorID, purchaser: Purchaser))
                return;

            if ((MaterialDelivered != null) &&
                MaterialDelivered(_materialVM))
                OutwardMaterialCollection.Remove(_materialVM);

            //Purchaser
        }

        internal void UpdateMaterialProperties(MaterialViewModel materialVM)
        {
            materialVM.Purchaser = Purchaser;
            materialVM.Date = Date;            
            Purchaser = string.Empty;
        }

        private void ExecuteDiscardCommand(object parameter)
        {
            string strmessage = string.Format("Do you want to discard the changes to  material '{0}'?", SelectedMaterial.MaterialName);
            var result = ShowConfirmationMessageBox(strmessage, "Deliver Material");
            if (!result)
                return;

            InitializeProperties();
            RaiseCanExecuteCommand();
        }

        public ObservableCollection<MaterialViewModel> OutwardMaterialCollection
        {
            get
            {
                return _OutwardMaterialCollection;
            }
        }

        public MaterialViewModel SelectedMaterial
        {
            get
            {
                if (_materialVM == null)
                {
                    _materialVM = _OutwardMaterialCollection.FirstOrDefault();
                    if(_materialVM != null)
                        OnPropertyChanged("SelectedMaterial");
                }
                return _materialVM;
            }
            set
            {
                _materialVM = value;
                OnPropertyChanged("SelectedMaterial");
            }
        }
    }
}
